package com.tyc.future;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestCompletableFuture {
    public static void main(String[] args){
        System.out.println("主线程 start");
        ExecutorService executor = Executors.newFixedThreadPool(10);
        /**
         * 基础API:
         * 建议使用自定义的线程池, 默认 ForkJoinPool 线程池
         * runAsync 无返回结果
         * supplyAsync 有返回结果
         * whenCompleteAsync 可以获取返回结果与异常没有返回值
         * handleAsync 可以获取返回结果与异常有返回值
         * exceptionally 获取异常有返回结果
         * 串行编排：
         *  thenRunAsync: 获取不到上一步结果 自身无返回值
         *  thenAcceptAsync 可以获取上一步结果 自身无返回值
         *  thenApplyAsync 可以获取上一步结果 有返回值
         * 任务都完成后向下执行：
         *  CompletableFuture.allOf(future1,future2,future3).join()
         * 任一任务完成
         *  CompletableFuture.anyOf(future1,future2,future3).join()
         */

        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + ":任务1执行");
            int a = 1/0;
        }, executor).whenCompleteAsync((result,exception)->{
            System.out.println("任务1 whenCompleteAsync result:"+result+",exception:"+exception);
        }).exceptionally((e)->{
            System.out.println("任务1产生异常");
            return null;
        });

        // 有返回结果
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + ":任务2执行");
            return "success";
        }, executor);

        future2.handleAsync((result,exception)->{
            if(null != exception){
                return "error";
            }else {
                return "success";
            }
        });

        future2.whenCompleteAsync((result,exception)->{
            System.out.println("任务2 whenCompleteAsync result:"+result+",exception:"+exception);
        });
        /**
         * thenRunAsync: 获取不到上一步结果 自身无返回值
         */
        CompletableFuture<Void> future3 = future2.thenRunAsync(() -> {
            System.out.println("运行任务3");
        }, executor);
        /**
         * thenAcceptAsync 可以获取上一步结果 自身无返回值
         */
        CompletableFuture<Void> future4 = future3.thenAcceptAsync((res) -> {
            System.out.println("任务4执行，获取到任务3的返回结果：" + res);
        }, executor);
        /**
         * thenApplyAsync 可以获取上一步结果 有返回值
         */
        CompletableFuture<String> future5 = future4.thenApplyAsync((res) -> {
            System.out.println("任务5执行，获取到任务3的返回结果：" + res);
            return "success3";
        });
        System.out.println("主线程 end");
    }
}
